<template>
  <q-btn :label="importText || $t('Import')" :loading="innerLoading" icon="cloud_upload" no-wrap outline
         text-color="primary" @click="handleImport"></q-btn>
  <q-btn :loading="innerLoading" class="q-ml-sm" no-wrap outline text-color="primary" @click="handleDownLoad">
    {{ downText || $t('TemplateDownload') }}
  </q-btn>

  <q-modal v-model="modalVisible" :header="`${importText || $t('Import')}`" :menuBtn="!readonly" width="600"
           @confirm="submitImport">
    <qx-table :data="errorList" :option="tableOption">
      <template v-slot:top>
        <q-uploader :factory="factoryFn" v-bind="uploadBind" @failed="failed" @finish="finishUpload"
                    @start="startUpload" @uploaded="uploaded">
          <template v-slot:header="scope">
            {{ getFiles(scope) }}
            <div class="row no-wrap items-center q-pa-sm q-gutter-xs">
              <q-btn v-if="scope.queuedFiles.length > 0" dense flat icon="clear_all" round
                     @click="scope.removeQueuedFiles"></q-btn>
              <q-btn v-if="scope.uploadedFiles.length > 0" dense flat icon="done_all" round
                     @click="scope.removeUploadedFiles"></q-btn>
              <q-spinner v-if="scope.isUploading" class="q-uploader__spinner" />
              <div class="col">
                <div class="q-uploader__title">{{ uploadBind.label }}</div>
                <div class="q-uploader__subtitle">{{ scope.uploadSizeLabel }} / {{ scope.uploadProgressLabel }}</div>
              </div>
              <q-btn v-if="scope.canAddFiles" dense flat icon="add_box" round type="a" @click="scope.pickFiles">
                <q-uploader-add-trigger />
              </q-btn>
            </div>
          </template>
        </q-uploader>
      </template>

      <template v-slot:menu="{ row }">
        <q-btn :loading="innerLoading" color="primary" dense flat icon="cloud_download" round
               @click="downLoadFile(row)" />
      </template>
    </qx-table>
  </q-modal>
</template>

<script setup>
import { baseURL } from 'boot/env'
import { i18n, toI18nName } from 'boot/i18n'
import QModal from 'components/Global/QModal.vue'
import QxTable from 'components/Global/QxTable.vue'
import { LoadingBar, Notify } from 'quasar'
import { postAPI } from 'src/api'
import { responseHandle } from 'src/axios/utils'
import { exportedStreamFile } from 'src/utils/utils'
import { userStores } from 'stores/user-stores'
import { computed, ref, watch } from 'vue'
import { useRoute } from 'vue-router'

const props = defineProps({
  downUrl: String,
  loading: Boolean,
  fileName: String,
  downText: String,
  importUrl: String,
  readonly: Boolean,
  downQuery: Object,
  errorParam: Array,
  downMethod: String,
  importText: String,
  importQuery: Object,
  importAfter: Function
})

const emits = defineEmits(['import-after'])

const route = useRoute()

const errorList = ref([])
const funcDone = ref(null)
const importScope = ref(null)
const modalVisible = ref(false)
const innerLoading = ref(false)
const url = computed(() => `${baseURL}${props.importUrl}`)
const uploadHeader = computed(() => {
  return [{
    name: 'Authorization', value: userStores().token
  }, {
    name: 'lang', value: i18n.locale.value
  }]
})
const uploadBind = computed(() => {
  return {
    batch: true,
    label: i18n.t('ImportTips'),
    accept: '.xls, .xlsx',
    readonly: props.readonly,
    'max-files': 1,
    color: 'grey-6',
    class: 'q-ma-sm',
    headers: uploadHeader.value
  }
})
const tableOption = computed(() => {
  return {
    menu: true,
    menuWidth: 100,
    rightBtn: false,
    column: [{
      label: `${i18n.t('Remarks')}`, field: 'remark', rowsNum: 3
    }, {
      label: `${i18n.t('CreationTime')}`, field: 'createdTime', width: 90
    }]
  }
})

watch(() => props.loading, () => (innerLoading.value = props.loading), { immediate: true })
watch(() => modalVisible.value, val => {
  if (!val && importScope.value) importScope.value.reset()
})

const factoryFn = () => {
  return {
    url: url.value,
    method: 'POST',
    fieldName: 'file',
    formFields: Object.keys((props.importQuery || {})).map(key => {
      return {
        name: key, value: props.importQuery[key]
      }
    })
  }
}

const getErrorList = () => {
  LoadingBar.stop()
  if (importScope.value) importScope.value.reset()

  if (!props.errorParam || !props.errorParam.length) {
    if (funcDone.value) funcDone.value(false)
    return
  }

  postAPI('/oss/api/ossUploadRecord/list', {
    pageNum: 1, pageSize: 3, serviceName: props.errorParam[0], bussinessModule: props.errorParam[1]
  }, data => {
    errorList.value = data.rows
    if (funcDone.value) funcDone.value(false)
  }, () => { if (funcDone.value) funcDone.value(false) })
}

const startUpload = () => {
  innerLoading.value = true
}
const finishUpload = () => {
  innerLoading.value = false
}
const failed = info => {
  if (info.xhr.response) {
    const error = JSON.parse(info.xhr.response)
    responseHandle(error.status, error)
  } else {
    Notify.create({ type: 'negative', message: i18n.t('UnknownError') })
    if (funcDone.value) funcDone.value(false)
    return
  }
  getErrorList()
}
const uploaded = info => {
  if (info.xhr.response) {
    const res = JSON.parse(info.xhr.response)
    if (res.code !== '0') {
      responseHandle(res.code, res)
      getErrorList()
      return
    }
    LoadingBar.stop()
    if (importScope.value) importScope.value.reset()

    if (props.importAfter) props.importAfter(res.data)
    emits('import-after', res.data)
  }
  if (funcDone.value) funcDone.value()
}
const handleImport = () => {
  modalVisible.value = true
}
const formatFileName = computed(() => {
  if (props.fileName) return props.fileName
  const { meta = {} } = route
  return `${meta[toI18nName('menuZhCn')] || ''}${i18n.t('ImportTemplate')}`
})
const handleDownLoad = () => {
  innerLoading.value = true
  exportedStreamFile({
    dicUrl: props.downUrl,
    dicQuery: props.downQuery || {},
    fileName: formatFileName.value,
    dicMethod: props.downMethod || 'post',
    done: () => {
      innerLoading.value = false
    }
  })
}
const downLoadFile = file => {
  innerLoading.value = true
  exportedStreamFile({
    dicUrl: '/oss/api/ossUploadRecord/download',
    dicQuery: { path: file.resultPath },
    fileName: file.name || file.originalFileName,
    dicMethod: 'get',
    done: () => {
      innerLoading.value = false
    }
  })
}

const getFiles = scope => {
  importScope.value = scope
}

const submitImport = done => {
  if (importScope.value) {
    if (!importScope.value.files.length) {
      Notify.create({ type: 'negative', message: i18n.t('ImportNonFiles') })
      done(false)
      return
    }
    importScope.value.upload()
  }
  funcDone.value = done
}

</script>